package SERVER;

/**
 * Klasa reprezentuj�ca r�ke gracza tj. 4 karty. Posiada metodody liczace warto�c uk�adu jaki ma gracz, sortowania kart.
 * Mo�na odnosic sie do poszczeg�lnych kart.
 * @author Sk�rcia
 *
 */
public class Hand {
	private Card [] card;
	/**
	 * Konstruktor tworzy 4 puste karty.
	 */
	Hand()
	{
		card = new Card[4];
		for (int i=0; i<card.length; i++)
		{
			card[i] = new Card(0);
		}
	}
	/**
	 * Ustawia warto�c wybranej karty po nr ID
	 * @param card_id ID na kt�re ma by ustawiona karta.
	 */
	public Card getCard(int card_id)
	{
		return card[card_id];
	}
	public void setCard(int card_number, int card_id)
	{
		card[card_number].setCard(card_id);
	}
	/**
	 * Ustawia warto�c wybranej karty po kolorze i warto�ci
	 * @param card_number card_number kt�ra karta ma byc ustawiona (0..3)
	 * @param card_color kolor na kt�ry ma byc ustawiona karta
	 * @param card_value warto�c na kt�r� ma byc ustawiona karta
	 */
	public void setCard(int card_number, int card_color, int card_value)
	{
		card[card_number].setCard(card_color, card_value);
	}
	/**
	 * Zwraca warto�c wybranej karty
	 * @param card_number Wyb�r karty
	 * @return warto�c
	 */
	public int getCardValue(int card_number)
	{
		return card[card_number].getValue();
	}
	/**
	 * Zwraca kolor wybranej karty
	 * @param card_number Wyb�r karty
	 * @return kolor
	 */
	public int getCardColor(int card_number)
	{
		return card[card_number].getColor();
	}
	/**
	 * Metoda sortuj�ca karty po wartosciach. Nie bierze pod uwag� ich kolor�w.
	 */
	private Card [] sortCards(Card [] cards) //metoda opiera sie na zwyk�ym sortowaniu babelkowym
	{
		int changed;
		do
		{
			changed = 0;
			for (int i=0; i<cards.length-1; i++)
			{
				if (cards[i].getValue()>cards[i+1].getValue())
				{
					int tmp_id = cards[i].getId();
					cards[i].setCard(cards[i+1].getId());
					cards[i+1].setCard(tmp_id);
					changed++;
				}
			}
		}
		while(changed>0);
		return cards;
	}
	public void sortCards()
	{
		card = sortCards(card);
	}
	public Card[] chooseCardsToCheck()
	{
		//Liczenie ile r�nych kolor�w znajduje si� w r�ce
		int [] cards_colors = new int [4];
		for (int i=0 ;i<4; i++)
		{
			//System.out.println("91 linijka wpisuje w komorke ++ " + (card[i].getColor()-1));
			cards_colors[card[i].getColor()-1]++;//!!
		}
		int colors =0;
		for (int i=0; i<4; i++)
		{
			if (cards_colors[i]!=0) colors++;
		}
		//wybieranie kart dla 4 kolor�w w r�ce
		if (colors==4)
		{
			int [] cards_values = new int [13];
			for (int i=0; i<card.length; i++)
			{
				//System.out.println("104 linijka wpisuje w komorke ++ " + (card[i].getValue()-1));
				cards_values[card[i].getValue()-1]++;
			}
			int counter = 0;
			//zliczanie wartosci
			for (int i=0; i<cards_values.length; i++)
			{
				if (cards_values[i]!=0) counter++;
			}
			if (counter==4) return card;
			if (counter==3)
			{
				Card [] cards_tmp = new Card [3];
				int j=0;
				for (int i=0; i<card.length; i++)
				{
					if (cards_values[card[i].getValue()-1]==1)
					{
						cards_tmp[j]=card[i];
						j++;
					}
					if (cards_values[card[i].getValue()-1]==2)
					{
						cards_tmp[2]=card[i];
					}
				}
				return cards_tmp;
			}
			if (counter==2)
			{
				Card [] cards_tmp = new Card [2];
				int j=0;
				for (int i=0; i<cards_values.length; i++)
				{
					System.out.println(cards_values[i]);
				}
				for (int i=0; i<card.length; i++)
				{
					if (cards_values[card[i].getValue()-1]!=0)// do poprawki!!! reszta hula
					{
						//System.out.println("wpisuje do cards_tmp["+j+"]=card["+i+"]");
						cards_tmp[j]=card[i];
						j++;
						cards_values[card[i].getValue()-1]=0;
					}
				}
				return cards_tmp;
			}
			if (counter==1)
			{
				Card [] cards_tmp = new Card[1];
				cards_tmp[0] = card[0];
				return cards_tmp;
			}
		}
		if (colors==3)
		{
			//szukamy powtarzajacego sie koloru
			int repeated_color = 0;
			for (int i=0; i<4; i++)
			{
				if (cards_colors[i]==2) repeated_color = i+1;
			}
			Card [] card_tmp = new Card[3];
			Card [] card_color = new Card[2];
			int j=0;
			int k=0;
			for (int i=0; i<4; i++) //wpisuje niepowtarzajace sie karty do jednej tyablicy i powtarzajace sie kolorami do drugiej
			{
				if (card[i].getColor()!=repeated_color)
				{
					card_tmp[j] = card[i];
					j++;			
				}
				else
				{
					card_color[k] = card[i];
					k++;
				}
			}
			if (card_color[0].getValue()<card_color[1].getValue()) j=0; else j=1; //wybieram index mniejszej karty
			k = 1-j;
			if (card_color[j].getValue()!=card_tmp[0].getValue() && card_color[j].getValue()!=card_tmp[1].getValue())
			{
				card_tmp[2]=card_color[j];
				return card_tmp;
			}
			if (card_color[k].getValue()!=card_tmp[0].getValue() && card_color[k].getValue()!=card_tmp[1].getValue())
			{
				card_tmp[2]=card_color[k];
				return card_tmp;
			}
			// jesli obie wartosci sie powtarzaja zwracamy tylko 2 karty
			Card [] card_tmp2 = new Card [2];
			card_tmp2[0] = card_tmp[0];
			card_tmp2[1] = card_tmp[1];
			return card_tmp2;
			
		}
		if (colors==2)
		{
			int [] color = new int [2];
			int [] ammount = new int [2];
			//sprawdzanie id wystepujacych kolorow
			for (int i=0; i<card.length; i++)
			{
				if (color[0] == 0)
				{
					color[0] = card[i].getColor();
				}
				else
				{
					if (card[i].getColor() != color[0]) color[1] = card[i].getColor();
				}
			}
			//zliczanie ile kart danego koloru znajduje sie w rece
			for (int i=0; i<card.length; i++)
			{
				if (card[i].getColor() == color[0]) ammount[0]++;
				if (card[i].getColor() == color[1]) ammount[1]++;
			}
			//System.out.println("Wykryte 2 kolory po id to:" + color[0] + " i " + color[1] + " w ilosci: " + ammount[0] + ", " + ammount[1]);
			if (ammount[0]==3 || ammount[1]==3)
			{
				int bigger_index;
				if (ammount[0]==3) bigger_index=0; else bigger_index=1;
				Card [] triple = new Card [3];
				Card one = new Card(0);
				int j=0;
				for (int i=0; i<card.length; i++)
				{
					if (card[i].getColor()==color[bigger_index])
					{
						triple[j]=card[i];
						j++;
					}
					else
					{
						one = card[i];
					}
					
				}
				triple = sortCards(triple);
				Card [] to_return = new Card[2];
				if (triple[0].getValue() != one.getValue())
				{
					to_return[0] = triple[0];
					to_return[1] = one;
				}
				else
				{
					to_return[0] = triple[1];
					to_return[1] = one;
				}
				return to_return;
			}
			if (ammount[0]==2 && ammount[1]==2)
			{
				Card [] card_color1 = new Card[2];
				Card [] card_color2 = new Card[2];
				int counter1 =0;
				int counter2 =0;
				for (int i=0; i<card.length; i++)
				{
					if (card[i].getColor()==color[0])
					{
						card_color1[counter1] = card[i];
						counter1++;
					}
					else
					{
						card_color2[counter2] = card[i];
						counter2++;
					}
				}
				card_color1 = sortCards(card_color1);
				card_color2 = sortCards(card_color2);
				Card [] to_return = new Card [2];
				if (card_color1[0].getValue() != card_color2[0].getValue())
				{
					to_return[0] = card_color1[0];
					to_return[1] = card_color2[0];
				}
				else
				{
					if (card_color1[1].getValue() < card_color2[1].getValue())
					{
						to_return[0] = card_color2[0];
						to_return[1] = card_color1[1];
					}
					else
					{
						to_return[0] = card_color1[0];
						to_return[1] = card_color2[1];
					}
				}
				return to_return;
			}
		}
		Card [] sorted = new Card [4];
		Card [] one_to_return = new Card [1];
		sorted = sortCards(card);
		one_to_return[0] = sorted[0];
		return one_to_return; //
	}
	private int countHandSystemPower(Card [] cards)
	{
		cards = sortCards(cards);
		int system_value = 0;
		for (int i=0; i<cards.length; i++)
		{
			system_value += ((14-cards[i].getValue())*((int)Math.pow(13,i)));
			//System.out.println(system_value);
		}
		return system_value;
	}
	public int handValue()
	{
		return countHandSystemPower(chooseCardsToCheck());
	}
	
	
}
